home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / p063b9s.zip / UNIT / ISRES.PAS < prev    next >
Pascal/Delphi Source File  |  1996-04-20  |  6KB  |  192 lines

  1. {$S-,R-,V-,I-,B-,F-}
  2.  
  3. {*********************************************************}
  4. {*                    ISRES.PAS 1.00                     *}
  5. {*        Copyright (c) TurboPower Software 1990.        *}
  6. {*                  All rights reserved.                 *}
  7. {*********************************************************}
  8.  
  9. unit IsRes;
  10.   {-Routines that allow a program to determine if another copy of itself is
  11.     already resident in memory}
  12.  
  13. interface
  14.  
  15. USES Use32;
  16.  
  17. type
  18.   ProgramName = string[8];
  19.  
  20. procedure Install(Name : ProgramName; UserHook : Pointer);
  21.   {-Install this program}
  22.  
  23. procedure Uninstall;
  24.   {-Uninstall this program}
  25.  
  26. function IsLoaded(Name : String; var UserHook : Pointer) : Boolean;
  27.   {-Returns True if Name is loaded}
  28.  
  29. procedure Init16;
  30.   {-Install interrupt handler. Called automatically when program begins}
  31.  
  32. procedure Restore16;
  33.   {-Restore INT $16 vector. Called automatically when program ends}
  34.  
  35.   {==========================================================================}
  36.  
  37. implementation
  38.  
  39. type
  40.   IfcPtr = ^IfcRecord;
  41.   IfcRecord =               {*** do not change!! ***}
  42.     record
  43.       NamePtr : ^String;
  44.       Version : Word;
  45.       UserPtr : Pointer;
  46.       PrevIfc : IfcPtr;
  47.       NextIfc : IfcPtr;
  48.       PrgName : ProgramName;
  49.     end;
  50. const
  51.   IfcSignature1   = $0F0F0;    {*** do not change!! ***}
  52.   IfcSignature2   = $0E0E0;    {*** do not change!! ***}
  53. var
  54.   SaveExitProc    : Pointer;
  55.   ThisIfcPtr      : IfcPtr;
  56.   IfcInstalledPtr : ^Boolean;
  57.  
  58.   {$L ISRES.OBJ}
  59.  
  60.   procedure Init16; external;
  61.   procedure Restore16; external;
  62.   procedure ThisIfc; external;
  63.  
  64.   function GetLastModulePtr : IfcPtr;
  65.     {-Return a pointer to the last module loaded before us}
  66.   var
  67.     FoundIfc : Boolean;
  68.     P : IfcPtr;
  69.     IACAptr : Pointer absolute $40:$F0;
  70.     SaveIACA : Pointer;
  71.   begin
  72.     {assume failure}
  73.     P := nil;
  74.     SaveIACA := IACAptr;
  75.     IACAptr := nil;
  76.  
  77.     inline(
  78.       $B8/>IfcSignature1/    {mov ax,>IfcSignature1  ;standard interface function code}
  79.       $31/$FF/               {xor di,di              ;es:di = nil}
  80.       $8E/$C7/               {mov es,di}
  81.       $CD/$16/               {int $16                ;call INT 16}
  82.       $F7/$D0/               {not ax                 ;flip bits}
  83.       $3D/>IfcSignature1/    {cmp ax,>IfcSignature1  ;AX = IfcSignature1 only if INT 16 flipped bits}
  84.       $75/$1E/               {jne Done               ;Ifc handler not found?}
  85.       $8C/$C0/               {mov ax,es              ;use second method if es:di = nil}
  86.       $09/$F8/               {or ax,di}
  87.       $74/$08/               {jz NotFound}
  88.       $89/$7E/<P/            {mov [bp+<P],di         ;offset of list pointer in P}
  89.       $8C/$46/<P+2/          {mov [bp+<P+2],es       ;segment of list pointer in P}
  90.       $EB/$0C/               {jmp short Found}
  91.                              {NotFound:              ;try second method - SuperKey can defeat the first}
  92.       $B8/>IfcSignature2/    {mov ax,>IfcSignature2  ;secondary function code}
  93.       $CD/$16/               {int $16                ;call INT 16}
  94.       $F7/$D0/               {not ax                 ;AX = not AX}
  95.       $3D/>IfcSignature2/    {cmp ax,>IfcSignature2  ;AX = IfcSignature2?}
  96.       $75/$04/               {jne Done               ;Ifc handler not found?}
  97.                              {Found:}
  98.       $C6/$46/<FoundIfc/$01);{mov [bp+<FoundIfc],1   ;set Found flag}
  99.                              {Done:}
  100.  
  101.       if not FoundIfc then
  102.         GetLastModulePtr := nil
  103.       else if P <> nil then
  104.         GetLastModulePtr := P
  105.       else
  106.         GetLastModulePtr := IACAptr;
  107.  
  108.       {restore intra-applications comm. area}
  109.       IACAptr := SaveIACA;
  110.   end;
  111.  
  112.   procedure Install(Name : ProgramName; UserHook : Pointer);
  113.     {-Install this program}
  114.   var
  115.     P : IfcPtr;
  116.   begin
  117.     if (Name <> '') and not IfcInstalledPtr^ then
  118.       with ThisIfcPtr^ do begin
  119.         {see if anyone else is home}
  120.         P := GetLastModulePtr;
  121.         if P <> nil then begin
  122.           P^.NextIfc := ThisIfcPtr;
  123.           PrevIfc := P;
  124.         end
  125.         else
  126.           PrevIfc := nil;
  127.  
  128.         {initialize the other fields in the record}
  129.         PrgName := Name;
  130.         NextIfc := nil;
  131.         UserPtr := UserHook;
  132.  
  133.         IfcInstalledPtr^ := True;
  134.       end;
  135.   end;
  136.  
  137.   procedure Uninstall;
  138.     {-Uninstall this program}
  139.   begin
  140.     if IfcInstalledPtr^ then
  141.       with ThisIfcPtr^ do begin
  142.         {fix the linked list of modules}
  143.         if PrevIfc <> nil then
  144.           PrevIfc^.NextIfc := NextIfc;
  145.         if NextIfc <> nil then
  146.           NextIfc^.PrevIfc := PrevIfc;
  147.         IfcInstalledPtr^ := False;
  148.       end;
  149.   end;
  150.  
  151.   function IsLoaded(Name : String; var UserHook : Pointer) : Boolean;
  152.     {-Returns True if Name is loaded}
  153.   var
  154.     P : IfcPtr;
  155.   begin
  156.     {search backward through the list}
  157.     P := GetLastModulePtr;
  158.     while (P <> nil) do begin
  159.       if P^.NamePtr^ = Name then begin
  160.         UserHook := P^.UserPtr;
  161.         IsLoaded := True;
  162.         Exit;
  163.       end;
  164.       P := P^.PrevIfc;
  165.     end;
  166.  
  167.     {search failed}
  168.     IsLoaded := False;
  169.   end;
  170.  
  171.   procedure OurExitProc; far;
  172.     {-Error/exit handler}
  173.   begin
  174.     {restore previous exit handler}
  175.     ExitProc := SaveExitProc;
  176.  
  177.     {remove the program from the list}
  178.     Uninstall;
  179.  
  180.     {restore INT $16}
  181.     Restore16;
  182.   end;
  183.  
  184. begin
  185.   {take over INT $16 and initialize pointers}
  186.   Init16;
  187.  
  188.   {set up exit handler}
  189.   SaveExitProc := ExitProc;
  190.   ExitProc := @OurExitProc;
  191. end.
  192.